﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Windows.Forms;

namespace SINGenerator
{
    class SIN
    {
        public ArrayList history;

        public SIN()
        {
            history = new ArrayList();
        }

        public String GetSINSpaces()
        {
            return InsertSeparator(GetSIN(RandomNumber()), " ");
        }

        public String GetSINHyphens()
        {
            return InsertSeparator(GetSIN(RandomNumber()), "-");
        }

        public String GetCustomSIN(int series)
        {
            return GetSIN(CustomRandomNumber(series));
        }

        public String GetSIN()
        {
            return GetSIN(RandomNumber());
        }

        private String GetSIN(String SIN)
        {
            //String SIN = RandomNumber();

            char[] tempCh = SIN.ToCharArray();
            Array.Reverse(tempCh);
            String ReversedSIN = new String(tempCh);

            int sum = 0;
            int pos = 0;
            int length = 9;
            int odd;

            while (pos < length - 1)
            {
                odd = int.Parse(ReversedSIN[pos].ToString()) * 2;

                if (odd > 9)
                    odd -= 9;

                sum += odd;

                if (pos != (length - 2))
                {
                    sum += int.Parse(ReversedSIN[pos + 1].ToString());
                }
                pos += 2;
            }

            int checkdigit = (((int)Math.Floor((double)(sum / 10)) + 1) * 10 - sum) % 10;

            SIN += checkdigit.ToString();

            history.Add(InsertSeparator(SIN, "-") + ";" + System.DateTime.Now.ToString());

            return SIN;
        }

        public bool CheckSIN(String SINstr)
        {
            string SINnum = ExtractNumbers(SINstr);

            if (SINnum.Length != 9)
                return false;
            else
                return IsLuhnValid(SINnum);

        }

        public String RemoveSeparator(String SINstr)
        {
            String temp = SINstr;
            temp = temp.Remove(3, 1);
            temp = temp.Remove(6, 1);
            return temp;
        }

        public String InsertSeparator(String SINstr, String sep)
        {
            SINstr = SINstr.Insert(3, sep);
            SINstr = SINstr.Insert(7, sep);
            return SINstr;
        }
        
        private String RandomNumber()
        {
            String SIN = String.Empty;
            Random rand = new Random((int)(System.DateTime.Now.Ticks));
            for (int i = 0; i < 8; i++)
            {
                if (i == 0)
                    SIN += rand.Next(9) + 1;
                else
                    SIN += rand.Next(10);
            }

            return SIN;
        }

        private String CustomRandomNumber(int series)
        {
            String SIN = String.Empty;
            Random rand = new Random((int)(System.DateTime.Now.Ticks));
            for (int i = 0; i < 8; i++)
            {
                if (i == 0)
                    SIN += series;
                else
                    SIN += rand.Next(10);
            }

            return SIN;
        }

        private String ExtractNumbers(String SINstr)
        {
            String SINnum = "";
            for (int i = 0; i < SINstr.Length; i++)
                if ((char)SINstr[i] >= 48 && (char)SINstr[i] <= 57)
                    SINnum = SINnum + SINstr[i];

            return SINnum;
        }

        private  bool IsLuhnValid(string value)
        {
            int[] SIN = new int[9];
            for(int i=0;i<9;i++)
                SIN[i] = int.Parse(value[i].ToString());
            return CheckNumber(SIN);
        }

        bool CheckNumber(int[] digits)
        {
            int sum = 0;
            bool alt = false;
            for (int i = digits.Length - 1; i >= 0; i--)
            {
                if (alt)
                {
                    digits[i] *= 2;
                    if (digits[i] > 9)
                    {
                        digits[i] -= 9;
                    }
                }
                sum += digits[i];
                alt = !alt;
            }
            return sum % 10 == 0;
        }


    }
}
